package icu.lookyousmileface.nio.basic;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 * @author shenj
 * @title: GroupToChatWithServer
 * @projectName NettyPro
 * @date 2020/12/1 22:53
 */
public class GroupToChatWithServer {

    private Selector selector;
    private ServerSocketChannel serverSocketChannel;
    private static final int Port = 7799;
    /**
     * @author shenj
     * @title:  GroupToChatWithServer
     * @date 2020/12/2  14:18
     * 无参构造
     * */
    public GroupToChatWithServer() {

        try {
            selector = Selector.open();
            serverSocketChannel = ServerSocketChannel.open();

            serverSocketChannel.socket().bind(new InetSocketAddress(Port));

            serverSocketChannel.configureBlocking(false);

            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * @author shenj
     * @title: listen
     * @date 2020/12/2  14:13
     *多路复用器监听channel通道的事件
     */
    public void listen() {

        try {

            while (true) {

                int status = selector.select();
                if (status > 0) {

                    Set<SelectionKey> selectionKeys = selector.selectedKeys();
                    Iterator<SelectionKey> key_Iterator = selectionKeys.iterator();
                    key_Iterator.forEachRemaining(s -> {
                        if (s.isAcceptable()) {
                            try {
                                SocketChannel socketChannel = serverSocketChannel.accept();
                                socketChannel.configureBlocking(false);
                                socketChannel.register(selector, SelectionKey.OP_READ);
                                System.out.println(socketChannel.getRemoteAddress()+"上线了");
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        if(s.isReadable()){
                            readData(s);
                        }
                        key_Iterator.remove();
                    });

                } else {
//                    System.out.println("等待中....");
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }
    /**
     * @author shenj
     * @title: readData
     * @date 2020/12/2  14:16
     * Listen监听到通道的read事件，读取信息
     */
    private void readData(SelectionKey key){

        SocketChannel socketChannel = null;
        try{
            socketChannel = (SocketChannel) key.channel();
            ByteBuffer dataBuffer = ByteBuffer.allocate(1024);
            int readCount = socketChannel.read(dataBuffer);

            if (readCount>0){
                String msg = new String(dataBuffer.array());
                System.out.println("from 客户端"+msg);
                sendInfo(msg,socketChannel);
            }

        }catch (Exception e){
            try {
                System.out.println(socketChannel.getRemoteAddress()+"下线了");
                key.cancel();
                socketChannel.close();
            } catch (IOException e2) {
                e2.printStackTrace();
            }
        }
    }
    /**
     * @author shenj
     * @title: sendInfo
     * @date 2020/12/2  14:17
     * 发送信息到其他的客户端
     */
    private void sendInfo(String msg, SocketChannel self){
        System.out.println("服务器发送信息中...");
        selector.selectedKeys().stream().forEach(s->{
            Channel targetChannel = s.channel();
            //排除自己发送
            if (targetChannel instanceof SocketChannel && targetChannel != self){
                SocketChannel dest = (SocketChannel)targetChannel;
                ByteBuffer dataBuffer = ByteBuffer.wrap(msg.getBytes());
                try {
                    dest.write(dataBuffer);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

    }
    /**
     * @author shenj
     * @title: main
     * @date 2020/12/2  14:19
     * 主方法
     */
    public static void main(String[] args) {
        GroupToChatWithServer chatWithServer = new GroupToChatWithServer();
        chatWithServer.listen();
    }
}
